#region Copyright

// The contents of this file are subject to the Mozilla Public License
//  Version 1.1 (the "License"); you may not use this file except in compliance
//  with the License. You may obtain a copy of the License at
//  
//  http://www.mozilla.org/MPL/
//  
//  Software distributed under the License is distributed on an "AS IS"
//  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
//  License for the specific language governing rights and limitations under 
//  the License.
//  
//  The Initial Developer of the Original Code is Robert Smyth.
//  Portions created by Robert Smyth are Copyright (C) 2008.
//  
//  All Rights Reserved.

#endregion

using System.Text;
using System.Text.RegularExpressions;
using System.Xml;


namespace NUnitGrid.GridClient.Plugins.GridClient.NUnitTestsFinder
{
    public class NUnitOutputParser
    {
        private readonly string endOfXmlPattern = Regex.Escape("</test-results>");
        private readonly string startOfXmlPattern = Regex.Escape("<?xml");
        private readonly string textOutput;
        private XmlDocument xmlDocument;
        private string xmlText;

        public NUnitOutputParser(string textOutput)
        {
            this.textOutput = textOutput;
        }

        private XmlDocument XmlDocument
        {
            get
            {
                if (xmlDocument == null)
                {
                    xmlDocument = new XmlDocument();
                    var xmlText = Xml;
                    if (xmlText.Length > 0)
                    {
                        xmlDocument.LoadXml(xmlText);
                    }
                }
                return xmlDocument;
            }
        }

        private string Xml
        {
            get
            {
                if (xmlText == null)
                {
                    var regex = new Regex(string.Format("{0}.*{1}", startOfXmlPattern, endOfXmlPattern),
                                          RegexOptions.Multiline | RegexOptions.Singleline);
                    xmlText = regex.Match(textOutput).Value;
                }
                return xmlText;
            }
        }

        public string GetSummaryText()
        {
            string summaryText;

            if (Xml != string.Empty)
            {
                var prefix = string.Empty;
                var suffix = string.Empty;

                var regex =
                    new Regex(string.Format("^(?<prefix>.*){0}.*{1}(?<suffix>.*)$", startOfXmlPattern, endOfXmlPattern),
                              RegexOptions.Singleline);
                var matches = regex.Matches(textOutput);
                if (matches.Count == 1)
                {
                    prefix = matches[0].Groups["prefix"].Success ? matches[0].Groups["prefix"].Value : string.Empty;
                    suffix = matches[0].Groups["suffix"].Success ? matches[0].Groups["suffix"].Value : string.Empty;
                }
                summaryText = string.Format("{0}\n{1}", prefix, suffix);
            }
            else
            {
                summaryText = textOutput;
            }

            return summaryText;
        }

        public string GetFailureText()
        {
            var stringBuilder = new StringBuilder();

            if (Xml != string.Empty)
            {
                var nodes = XmlDocument.SelectNodes("//failure");
                foreach (XmlNode node in nodes)
                {
                    var messageNode = node.SelectSingleNode("message");
                    stringBuilder.AppendLine();
                    stringBuilder.AppendLine("Reason:");
                    stringBuilder.AppendLine(messageNode.InnerText);

                    var stackTraceNode = node.SelectSingleNode("stack-trace");
                    if (stackTraceNode != null)
                    {
                        stringBuilder.AppendLine();
                        stringBuilder.AppendLine("Stack trace:");
                        stringBuilder.AppendLine(stackTraceNode.InnerText);
                    }
                }
            }

            return stringBuilder.ToString();
        }
    }
}